package cn.itsy.utils;

import cn.itsy.pojo.User;
import cn.itsy.service.log.LogService;
import cn.itsy.web.controller.SysLogController;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * @description:
 * @author: MisterGay
 * @date: 2019-06-11 8:59
 */
@Component
@Aspect
@SuppressWarnings("all")
public class AopLog {
    private Class executeClass;//访问的类
    private Method executeMethod;//执行的方法名称
    private long startTime;//执行时长
    @Autowired
    private LogService logService;
    @Autowired
    private HttpSession Session;
    @Autowired
    private HttpServletRequest request;

    @Before("execution(* cn.itsy.web.controller.*.*(..))")
    public void doBefore(JoinPoint joinPoint) {
        this.startTime = new Date().getTime();
        this.executeClass = joinPoint.getTarget().getClass();
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
//        User user = new User();
//        user.setId(1);
//        user.setUname("迪丽热巴");
//        this.Session.setAttribute("user",user);
        if (args == null || args.length == 0) {
            try {
                executeMethod = executeClass.getMethod(methodName);
            } catch (NoSuchMethodException e) {
                System.out.println("没有该方法");
            }
        } else {
            Class[] classArgs = new Class[args.length];
            for (int i = 0; i < classArgs.length; i++) {
                if (args[i] != null) {
                    if (args[i] instanceof Model) {
                        classArgs[i] = Model.class;
                    } else {
                        classArgs[i] = args[i].getClass();
                    }
                }
            }
            try {
                executeMethod = executeClass.getMethod(methodName, classArgs);
            } catch (NoSuchMethodException e) {
                System.out.println("没有该方法");
            }
        }
    }

    //        组装日志相关信息
    @After("execution(* cn.itsy.web.controller.*.*(..))")
    public void doAfter(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ParseException {
        if (this.executeClass != null && this.executeMethod != null && this.executeClass != SysLogController.class) {
            Syslog sysLog = new Syslog();
            String url = "";
            Annotation classAnnotation = executeClass.getAnnotation(RequestMapping.class);
//            类上的注解
            if (classAnnotation != null) {
                Object invoke = classAnnotation.annotationType().getDeclaredMethod("value").invoke(classAnnotation);
                if (invoke.getClass().isArray()) {
                    url += ((Object[]) invoke)[0].toString();
                }
            }
//            方法上的注解
            Annotation methodAnnotation = executeMethod.getAnnotation(RequestMapping.class);
            if (methodAnnotation != null) {
                Object invoke = methodAnnotation.annotationType().getDeclaredMethod("value").invoke(methodAnnotation);
                if (invoke.getClass().isArray()) {
                    url += ((Object[]) invoke)[0].toString();
                }
            }
            long executeTime = new Date().getTime() - startTime;
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String format = dateFormat.format(new Date(startTime));
            sysLog.setVisitTime(dateFormat.parse(format));
            sysLog.setMethod("[类名]" + executeClass.getName() + "[方法名]" + executeMethod.getName());
            sysLog.setUrl(url);
            sysLog.setExecutionTime(executeTime);
            User user = (User) this.Session.getAttribute("user");
            String uname = user.getUname();
            String ip = request.getRemoteAddr();
            sysLog.setUsername(uname);
            sysLog.setIp(ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip);
            sysLog.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            String sql = "insert into syslog values(?,?,?,?,?,?,?)";
            this.logService.saveLog(sql, sysLog);
        }
    }
}
